home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 23
/
Amiga Format AFCD23 (Feb 1998, Issue 107).iso
/
+look_here_1st!+
/
handy_tools
/
snoopdos
/
snoopdos_source
/
snoopdos.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-02-27
|
13KB
|
459 lines
/*
* SNOOPDOS.C vi:ts=4
*
* Copyright (c) Eddy Carroll, September 1994.
*
* The mainline, where we co-ordinate everything.
*/
#define MAIN
#define RAWDOFMT_COPY (void (*))"\x16\xc0\x4e\x75" /* MOVE.B D0,(A3)+ | RTS */
#include "system.h"
#include "snoopdos.h"
#define OldPrint(s) Write(Output(), s, strlen(s))
#define OldFPrint(f,s) Write(f, s, strlen(s))
#if _PROFILE
#include "sprof.h"
#else
#define PROFILE_ON()
#define PROFILE_OFF()
#endif
#define NAME "SnoopDos 3.0"
#define DATENAME "September 1994"
#define DATENUM "15.9.94"
char Version[] = "$VER: " NAME " (" DATENUM ")";
char SnoopDosTitle[] = NAME " \251 Eddy Carroll, " DATENAME ".";
char SnoopDosTitleKey[] = NAME " \251 Eddy Carroll, " DATENAME ". Hotkey=<%s>";
char CommodityTitle[] = NAME " by Eddy Carroll";
long __stack = MINSTACKSIZE; /* Ensure stack size is sufficient */
static ULONG StartPri; /* Start priority of our task */
/*
* Cleanup(errcode)
*
* Frees all resources allocated by the program and exits with
* the specified error code
*/
void Cleanup(int errcode)
{
CleanupHotKey();
CleanupWindows();
CleanupAGuide();
CleanupIcons();
CleanupLocale();
CleanupRexxPort();
CleanupPatches();
CleanupBuffers();
if (AslBase) CloseLibrary(AslBase);
if (RexxSysBase) CloseLibrary(RexxSysBase);
if (DiskfontBase) CloseLibrary(DiskfontBase);
if (GadToolsBase) CloseLibrary(GadToolsBase);
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (LayersBase) CloseLibrary(LayersBase);
if (GfxBase) CloseLibrary(GfxBase);
if (IconBase) CloseLibrary(IconBase);
if (UtilityBase) CloseLibrary(UtilityBase);
if (KeymapBase) CloseLibrary(KeymapBase);
if (CxBase) CloseLibrary(CxBase);
/*
* Restore our requester status and task priority before we
* exit, in case we were run from a CLI prompt
*/
*TaskWindowPtr = SaveWindowPtr;
SetTaskPri(SysBase->ThisTask, StartPri);
exit(errcode);
}
/*
* OpenLibs()
*
* Opens all the main libraries we'll need. We must have intuition,
* graphics, and gadtools, but everything else we can manage without.
*
* dos.library and exec.library will already be open at this point.
*
*/
void OpenLibs(void)
{
APTR oldwinptr = *TaskWindowPtr;
if (SysBase->LibNode.lib_Version < 37) {
if (WBenchMsg) {
/*
* Open a text window to display error message in.
*/
BPTR file = Open("CON:0/0/520/80/SnoopDos 3.0", MODE_NEWFILE);
if (file) {
char ch;
OldFPrint(file,
"\nSorry, " NAME " requires Workbench 2.04 or above."
"\n\nPress RETURN to close this window. ");
Read(file, &ch, 1);
Close(file);
}
} else {
/*
* Just print it in the CLI
*/
OldPrint("Sorry, " NAME " requires Workbench 2.04 or above.\n");
}
Cleanup(50);
}
IntuitionBase = (void *)OpenLibrary("intuition.library", 37);
GfxBase = (void *)OpenLibrary("graphics.library", 37);
LayersBase = OpenLibrary("layers.library", 37);
GadToolsBase = OpenLibrary("gadtools.library", 37);
IconBase = OpenLibrary("icon.library", 0);
RexxSysBase = OpenLibrary("rexxsyslib.library", 0);
UtilityBase = OpenLibrary("utility.library", 0);
KeymapBase = OpenLibrary("keymap.library", 37);
/*
* We don't need diskfont.library to run, but just in case we're
* run after booting with no startup-sequence, we disable AmigaDOS
* requesters so that diskfont.library doesn't ask us to insert
* volume ENV:
*/
*TaskWindowPtr = (APTR)-1;
DiskfontBase = OpenLibrary("diskfont.library", 0);
*TaskWindowPtr = oldwinptr;
CxBase = OpenLibrary("commodities.library", 37);
if (!IntuitionBase || !GfxBase || !LayersBase) {
OldPrint("Couldn't open intuition, graphics or layers libraries!\n");
Cleanup(50);
}
if (!GadToolsBase || !UtilityBase || !KeymapBase) {
OldPrint("Couldn't open gadtools, utilities or keymap library!\n");
Cleanup(50);
}
}
/*
* My own version of sprintf, using the exec routine. Saves pulling
* in a lot of unnecessary library routines (5-10K!)
*/
void mysprintf(char *outstr, char *fmtstr, ...)
{
RawDoFmt(fmtstr, &fmtstr+1, RAWDOFMT_COPY, outstr);
}
/*
* InstallSettings(set, which)
*
* Installs the specified set of settings into CurSettings, and
* adjusts any other variables that may be required to reflect
* these new settings.
*
* This includes updating the appropriate windows if necessary.
*/
void InstallSettings(Settings *set, int which)
{
int resetwin = 0;
int redrawwin = 0;
if (which & SET_FUNC) {
/*
* First, go down through the new function options and
* update the function window to match the new set of
* options. For speed, we only update those that are
* different.
*/
if (FuncWindow) {
ShowFuncOpts(set->Func.Opts, FIRST_BOOL_GADGET, LAST_BOOL_GADGET);
ResetFuncToSelected();
if (strcmp(CurSettings.Func.Pattern, set->Func.Pattern) != 0) {
GT_SetGadgetAttrs(Gadget[GID_MATCHNAME], FuncWindow, NULL,
GTST_String, set->Func.Pattern,
TAG_DONE);
}
}
CurSettings.Func = set->Func;
LoadFuncSettings(&set->Func);
}
if (which & SET_SETUP) {
struct SetupSettings *curset = &CurSettings.Setup;
struct SetupSettings *newset = &set->Setup;
char oldwinfont[MAX_SHORT_LEN+2];
char oldbuffont[MAX_SHORT_LEN+2];
int oldwinsize;
int oldbufsize;
if (!CxBase)
newset->HideMethod = HIDE_NONE;
if (SetWindow) {
/*
* Update settings window to reflect new gadget settings
*
* While we can optimise some of our update methods, we
* have to blindly ALWAYS update string gadgets since
* we have no way of knowing if they have been changed
* by the user in a way that was not yet detected by
* SnoopDos (e.g. entering a new value and forgetting
* to press RETURN).
*/
if (curset->HideMethod != newset->HideMethod)
GT_SetGadgetAttrs(Gadget[GID_HIDEMETHOD], SetWindow, NULL,
GTCY_Active, newset->HideMethod,
TAG_DONE);
if (curset->ScreenType != newset->ScreenType)
GT_SetGadgetAttrs(Gadget[GID_OPENON], SetWindow, NULL,
GTCY_Active, newset->ScreenType,
TAG_DONE);
if (curset->LogMode != newset->LogMode)
GT_SetGadgetAttrs(Gadget[GID_LOGMODE], SetWindow, NULL,
GTCY_Active, newset->LogMode,
TAG_DONE);
if (curset->FileIOType != newset->FileIOType)
GT_SetGadgetAttrs(Gadget[GID_FILEIO], SetWindow, NULL,
GTCY_Active, newset->FileIOType,
TAG_DONE);
GT_SetGadgetAttrs(Gadget[GID_BUFFERSIZE], SetWindow, NULL,
GTIN_Number, newset->BufferSize,
TAG_DONE);
GT_SetGadgetAttrs(Gadget[GID_HOTKEY], SetWindow, NULL,
GTST_String, newset->HotKey,
TAG_DONE);
GT_SetGadgetAttrs(Gadget[GID_SCREENNAME], SetWindow, NULL,
GTST_String, newset->ScreenName,
TAG_DONE);
GT_SetGadgetAttrs(Gadget[GID_LOGFILE], SetWindow, NULL,
GTST_String, newset->LogFile,
TAG_DONE);
GT_SetGadgetAttrs(Gadget[GID_BUFFORMAT], SetWindow, NULL,
GTST_String, newset->BufferFormat,
TAG_DONE);
GT_SetGadgetAttrs(Gadget[GID_LOGFORMAT], SetWindow, NULL,
GTST_String, newset->LogfileFormat,
TAG_DONE);
}
if (strcmp(curset->HotKey, newset->HotKey) != 0) {
InstallHotKey(newset->HotKey);
SetMainHideState(newset->HideMethod);
}
if (newset->HideMethod != curset->HideMethod) {
if (newset->HideMethod == HIDE_NONE)
CleanupHotKey();
else {
curset->HideMethod = newset->HideMethod;
InstallHotKey(newset->HotKey);
}
SetMainHideState(newset->HideMethod);
}
if (curset->BufferSize != newset->BufferSize) {
ClearWindowBuffer();
if (!SetTotalBufferSize(newset->BufferSize * 1024,
SETBUF_FORCENEW)) {
ShowError(MSG(MSG_ERROR_NOBUFMEM), newset->BufferSize);
Cleanup(20);
}
}
if (strcmp(curset->BufferFormat, newset->BufferFormat)) {
strcpy(curset->BufferFormat, newset->BufferFormat);
InstallNewFormat(NEW_STRING);
}
/*
* Since the font settings may have been reset to the default
* fonts (i.e. size = 0) we need to change them to actual
* font names before we check if they've changed. Thus, we
* must save the existing names first (since InitFonts()
* modifies the current settings directly and would trash
* them).
*/
strcpy(oldwinfont, curset->WindowFont);
strcpy(oldbuffont, curset->BufferFont);
oldwinsize = curset->WinFontSize;
oldbufsize = curset->BufFontSize;
if (curset->LogMode != newset->LogMode)
SetLogGadget(newset->LogMode, LG_REFRESH);
*curset = *newset; /* Copy in new settings */
if (curset->WinFontSize == 0 || curset->BufFontSize == 0)
InitFonts();
if (strcmp(oldbuffont, curset->BufferFont) != 0 ||
oldbufsize != curset->BufFontSize ||
strcmp(oldwinfont, curset->WindowFont) != 0 ||
oldwinsize != curset->WinFontSize)
{
/*
* Got a font change so update font info
* accordingly and set flag to say we need
* to reset the main window.
*/
extern struct TextAttr WindowFontAttr;
extern struct TextAttr BufferFontAttr;
WindowFontAttr.ta_YSize = curset->WinFontSize;
BufferFontAttr.ta_YSize = curset->BufFontSize;
resetwin = 1;
if (SetWindow) {
GT_SetGadgetAttrs(Gadget[GID_WINDOWFONT], SetWindow, NULL,
GTTX_Text, GetFontDesc(WindowFontDesc,
WindowFontName,
WindowFontSize),
TAG_DONE);
GT_SetGadgetAttrs(Gadget[GID_BUFFERFONT], SetWindow, NULL,
GTTX_Text, GetFontDesc(BufferFontDesc,
BufferFontName,
BufferFontSize),
TAG_DONE);
}
PurgeFuncGadgets = 1; /* Ensure function window gets updated */
if (!FuncWindow)
CloseFunctionWindow(); /* Free gadgets now if window closed */
}
/*
* Now update everything to take advantage of the new settings
*/
}
if ((which & SET_MAIN) == SET_MAIN) {
int updatefunc = set->StackLimit != CurSettings.StackLimit;
if (CurSettings.SimpleRefresh != set->SimpleRefresh)
resetwin = 1;
if (!resetwin && set->TextSpacing != BoxInterGap)
SetTextSpacing(set->TextSpacing);
else if (set->RightAlign != RightAligned && !resetwin && MainWindow) {
RightAligned = set->RightAlign;
ShowBuffer(TopSeq, DISPLAY_ALL);
}
if (set->ShowStatus != StatusLine || set->ShowGadgets != GadgetsLine)
redrawwin = 1;
CurSettings = *set; /* Copy all settings */
InitFonts(); /* Make sure fonts are current */
SetMenuOptions(); /* Update main menu if necessary */
if (updatefunc) {
/*
* If we changed our stack limit, re-install all the
* function settings ... this has the side effect of
* fixing up the stack on the way
*/
LoadFuncSettings(&set->Func);
}
}
if (resetwin) {
ReOpenMainWindow();
} else if (redrawwin) {
RecalcMainWindow(MainWindow->Width, MainWindow->Height, REDRAW_GADGETS);
}
}
/*
* MainLoop()
*
* Opens the main window, then processes all incoming events
*/
void MainLoop(void)
{
if (QuitFlag)
return;
if (HideOnStartup) {
HideSnoopDos();
} else {
if (!ShowSnoopDos()) {
ShowError(MSG(MSG_ERROR_INITGUI));
return;
}
}
while (!QuitFlag) {
ULONG mask;
PROFILE_OFF();
mask = Wait(MainWindowMask |
FuncWindowMask |
FormWindowMask |
SetWindowMask |
NewEventMask |
ScanDosListMask |
AmigaGuideMask |
CommodityMask |
RexxPortMask |
WorkbenchMask |
SIGBREAKF_CTRL_C |
SIGBREAKF_CTRL_D |
SIGBREAKF_CTRL_E |
SIGBREAKF_CTRL_F);
PROFILE_ON();
if (mask & MainWindowMask) HandleMainMsgs();
if (mask & FuncWindowMask) HandleFuncMsgs();
if (mask & FormWindowMask) HandleFormatMsgs();
if (mask & SetWindowMask) HandleSettingsMsgs();
if (mask & NewEventMask) HandleNewEvents();
if (mask & ScanDosListMask) UpdateDeviceList(SCANDEV_DELAY);
if (mask & AmigaGuideMask) HandleAGuideMsgs();
if (mask & CommodityMask) HandleHotKeyMsgs();
if (mask & RexxPortMask) HandleRexxMsgs();
if (mask & WorkbenchMask) HandleWorkbenchMsgs();
if (mask & SIGBREAKF_CTRL_C) QuitFlag = 1;
if (mask & SIGBREAKF_CTRL_D) SetMonitorMode(MONITOR_DISABLED);
if (mask & SIGBREAKF_CTRL_E) SetMonitorMode(MONITOR_NORMAL);
if (mask & SIGBREAKF_CTRL_F) ShowSnoopDos();
}
CleanupWindows();
}
int main(int argc, char **argv)
{
struct Process *myproc = (struct Process *)(SysBase->ThisTask);
TaskWindowPtr = &(myproc->pr_WindowPtr);
SaveWindowPtr = *TaskWindowPtr;
StartPri = SysBase->ThisTask->tc_Node.ln_Pri;
OpenLibs();
InitSettings();
InitTextTable();
InitRexxPort();
InitBuffers();
CheckSegTracker();
/*
* Now parse our startup options, read default configuration files
* and so on.
*/
if (!ParseStartupOpts(argc, argv))
Cleanup(0);
RestoreSettings = CurSettings; /* Record for later restoration */
MainLoop();
SetMonitorMode(MONITOR_DISABLED);
Cleanup(0);
return (0);
}